package com.utils.encode;

import org.apache.commons.io.FileUtils;

import java.io.*;
import java.util.*;

/**
 * 编码转换工具
 *
 * @author hury
 * @version 1.0
 * @date 2023-07-07 16:21
 * @description
 */
public class EncodingChangeUtil {
    /**
     * 配置文件名称
     */
    private static final String configFile= "config.properties";
    /**
     * 配置参数
     */
    private static Properties properties ;
    /**
     * 加载配置
     * @return true:执行成功，false：执行失败
     * */
    private static boolean loadConfig() throws IOException {
        File f = new File(configFile);
        // 如果本地配置文件，返回错误
        if(!f.exists()){
            System.out.println("未找到配置文件："+f.getAbsolutePath());
            System.out.println("请参考文件：[config.properties]");
            return false;
        }

        FileInputStream fis = new FileInputStream(f);
        InputStream is = new BufferedInputStream(fis);
        properties = new Properties();
        properties.load(is);
        fis.close();

        System.out.println("\n>>> 配置参数");
        // 打印配置参数
        for(Object k:properties.keySet()){
            String v =properties.getProperty((String) k);
            System.out.println(k+":"+v);
        }
        return true;
    }

    /**
     * 修正文件编码
     */
    public static boolean changeFileEncode() throws IOException {
        // 读取配置
        if(!loadConfig()) return false;
        // 源码路径
        String srcPath = properties.getProperty("src.path") ;
        // 转编码后的输出路径
        String targetPath = properties.getProperty("target.path") ;
        // 文件扩展名
        String fileExt = properties.getProperty("file.ext") ;
        // 源文件编码
        String srcEncoding = properties.getProperty("src.encoding");
        // 目标文件编码
        String targetEncoding = properties.getProperty("target.encoding") ;
        // 仅执行检查？true:仅进行编码检查，false:编码检查后，进行编码转换
        boolean checkOnly = Boolean.parseBoolean( properties.getProperty("check.only"));

        // 检查目录是否存在
        File f = new File(srcPath);
        if(!f.exists() ||!f.isDirectory()){
            System.out.println("源码目录不存在：["+srcPath+"],请重新设置！");
            return false;
        }
        f = new File(targetPath);
        if(!f.exists() ||!f.isDirectory()){
            System.out.println("输出目录不存在：["+targetPath+"],请重新设置！");
            return false;
        }

        // 进行转码
		changeFileEncode(srcPath, targetPath, fileExt, srcEncoding,targetEncoding,checkOnly);
        return true;
    }
    /**
     * 将源码转换为utf-8
     *
     * @param srcPath 源码路径
     * @param targetPath 目标输出路径
     * @param fileExt 文件扩展名
     * @param srcEncoding
     *                   原文件编码：
     *                   可用于限定仅转换指定源编码格式；
     *                   如果未指定，则转换全部
     * @param targetEncoding
     *            目标文件编码，如果编码不一致，自动转换为新编码
     * @param checkOnly true:仅进行编码检查，false:编码检查后，进行编码转换
     */
    private static void changeFileEncode(String srcPath, String targetPath, String fileExt, String srcEncoding
            , String targetEncoding, boolean checkOnly ) {
        try {
            System.out.println("\n>>> 分析文件编码：");
            EncodingDetect.checkFolder(srcPath, fileExt);

            if(checkOnly){
                System.out.println("只进行编码检查，不需要进行转换。");
                return;
            }

            System.out.println("\n>>> 转换文件编码：");
            int i=0;
            for (String encoding : EncodingDetect.resultsMap.keySet()) {
                List<String> list = EncodingDetect.resultsMap.get(encoding);
                System.out.println("\n源码格式 :"+encoding+",数量:"+list.size());

                // 编码格式一致，不需要处理
                if (encoding.equalsIgnoreCase(targetEncoding)){
                    System.out.println("编码格式相同，不需要处理！");
                    continue;
                }

                // 如果指定了源文件编码，且源文件编码 != 当前文件编码，则跳过处理
                if(null!=srcEncoding && !"".equals(srcEncoding) && !encoding.equalsIgnoreCase(srcEncoding)){
                    System.out.println("已指定需要转换的源文件编码:"+srcEncoding+", 跳过！");
                    continue;
                }
                // 文件编码转换
                for (String path : list) {
                    File file = new File(path);
                    // 目标文件路径
                    String outBasePath = targetPath + file.getAbsolutePath().substring(srcPath.length());
                    System.out.println((++i) +"\t:"+encoding + " => " + targetEncoding + "\t:\t" + outBasePath);
                    // 使用原始格式读取文件，然后用 destEncode格式 写入文件
                    FileUtils.writeLines(new File(outBasePath), targetEncoding, FileUtils.readLines(file, encoding));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
